package com.bookocean.controller;

import com.bookocean.application.common.Result;
import com.bookocean.application.service.RewardApplicationService;
import com.bookocean.controller.dto.RewardDto;
import com.bookocean.domain.utils.UserContextHolder;
import com.bookocean.infrastructure.persistence.po.UserPointsPO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import java.util.List;

/**
 * 奖励控制器
 * 
 * @author BookOcean
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/reward")
@RequiredArgsConstructor
public class RewardController {

    private final RewardApplicationService rewardApplicationService;

    /**
     * 获取所有可用奖励
     * 
     * @return 奖励列表
     */
    @GetMapping("/all")
    public Result<List<RewardDto>> getAllRewards() {
        log.info("获取所有可用奖励");
        
        List<RewardDto> rewards = rewardApplicationService.getAllRewards();
        return Result.success(rewards);
    }

    /**
     * 根据类型获取奖励
     * 
     * @param type 奖励类型
     * @return 奖励列表
     */
    @GetMapping("/type/{type}")
    public Result<List<RewardDto>> getRewardsByType(@PathVariable String type) {
        log.info("根据类型获取奖励，type: {}", type);
        
        List<RewardDto> rewards = rewardApplicationService.getRewardsByType(type);
        return Result.success(rewards);
    }

    /**
     * 根据积分范围获取奖励
     * 
     * @param minPoints 最小积分
     * @param maxPoints 最大积分
     * @return 奖励列表
     */
    @GetMapping("/points-range")
    public Result<List<RewardDto>> getRewardsByPointsRange(
            @RequestParam @NotNull @Positive Integer minPoints,
            @RequestParam @NotNull @Positive Integer maxPoints) {
        log.info("根据积分范围获取奖励，minPoints: {}, maxPoints: {}", minPoints, maxPoints);
        
        List<RewardDto> rewards = rewardApplicationService.getRewardsByPointsRange(minPoints, maxPoints);
        return Result.success(rewards);
    }

    /**
     * 获取当前用户可兑换的奖励列表
     * 
     * @return 奖励列表（包含可兑换状态）
     */
    @GetMapping("/available")
    public Result<List<RewardDto>> getAvailableRewards() {
        Long currentUserId = UserContextHolder.getUserId();
        log.info("获取当前用户可兑换的奖励列表，userId: {}", currentUserId);
        
        List<RewardDto> rewards = rewardApplicationService.getUserAvailableRewards(currentUserId);
        return Result.success(rewards);
    }

    /**
     * 获取奖励详情
     * 
     * @param rewardId 奖励ID
     * @return 奖励详情
     */
    @GetMapping("/{rewardId}")
    public Result<RewardDto> getRewardDetail(@PathVariable Long rewardId) {
        Long currentUserId = UserContextHolder.getUserId();
        log.info("获取奖励详情，rewardId: {}, userId: {}", rewardId, currentUserId);
        
        RewardDto reward = rewardApplicationService.getRewardDetail(rewardId, currentUserId);
        return Result.success(reward);
    }

    /**
     * 兑换奖励
     * 
     * @param rewardId 奖励ID
     * @return 兑换结果
     */
    @PostMapping("/{rewardId}/redeem")
    public Result<Boolean> redeemReward(@PathVariable Long rewardId) {
        Long currentUserId = UserContextHolder.getUserId();
        log.info("兑换奖励，rewardId: {}, userId: {}", rewardId, currentUserId);
        
        try {
            boolean result = rewardApplicationService.redeemReward(currentUserId, rewardId);
            return Result.success("奖励兑换成功", result);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }

    /**
     * 获取当前用户积分信息
     * 
     * @return 用户积分信息
     */
    @GetMapping("/points")
    public Result<UserPointsPO> getMyPoints() {
        Long currentUserId = UserContextHolder.getUserId();
        log.info("获取当前用户积分信息，userId: {}", currentUserId);
        
        UserPointsPO points = rewardApplicationService.getUserPoints(currentUserId);
        return Result.success(points);
    }

    /**
     * 获取指定用户的积分信息
     * 
     * @param userId 用户ID
     * @return 用户积分信息
     */
    @GetMapping("/points/{userId}")
    public Result<UserPointsPO> getUserPoints(@PathVariable Long userId) {
        log.info("获取指定用户积分信息，userId: {}", userId);
        
        UserPointsPO points = rewardApplicationService.getUserPoints(userId);
        return Result.success(points);
    }


    /**
     * 获取奖励中心页面数据（灵曜页面专用）
     * 
     * @return 奖励中心数据
     */
    @GetMapping("/center")
    public Result<RewardCenterDto> getRewardCenter() {
        Long currentUserId = UserContextHolder.getUserId();
        log.info("获取奖励中心页面数据，userId: {}", currentUserId);
        
        // 获取用户积分信息
        UserPointsPO userPoints = rewardApplicationService.getUserPoints(currentUserId);
        
        // 获取可兑换的奖励列表
        List<RewardDto> availableRewards = rewardApplicationService.getUserAvailableRewards(currentUserId);
        
        RewardCenterDto centerDto = new RewardCenterDto();
        centerDto.setUserPoints(userPoints);
        centerDto.setAvailableRewards(availableRewards);
        
        return Result.success(centerDto);
    }

    /**
     * 奖励中心数据传输对象
     */
    public static class RewardCenterDto {
        private UserPointsPO userPoints;
        private List<RewardDto> availableRewards;
        
        // Getters and Setters
        public UserPointsPO getUserPoints() {
            return userPoints;
        }
        
        public void setUserPoints(UserPointsPO userPoints) {
            this.userPoints = userPoints;
        }
        
        public List<RewardDto> getAvailableRewards() {
            return availableRewards;
        }
        
        public void setAvailableRewards(List<RewardDto> availableRewards) {
            this.availableRewards = availableRewards;
        }
    }
}
